package graph.property;

import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;

import graph.Edge;
import graph.Graph;
import graph.Node;

public class PlaneGraphProperty implements Property {

	/**
	 * All nodes must be in plane z=0
	 * No edges can cross other edge
	 */
	@Override
	public boolean fulfill(Graph<?,?> graph) {
		for (Node<?> node : graph.getNodes()) {
			if (node.pos.z != 0.0) return false;
		}
		for (int i=0 ; i<graph.getEdges().size()-1 ; i++) {
			Edge<?,?> a = graph.getEdges().get(i); 
			for (int j=i+1 ; j<graph.getEdges().size() ; j++) {
				Edge<?,?> b = graph.getEdges().get(j); 
				if (cross(a,b)) return false;
			}
		}
		return true;
	}

	private boolean cross(Edge<?, ?> a, Edge<?, ?> b) {
		double c1 = cross(a.a.pos, a.b.pos, b.a.pos);
		double c2 = cross(a.a.pos, a.b.pos, b.b.pos);
		if (c1*c2 >= 0) return false;
		double c3 = cross(b.a.pos, b.b.pos, a.a.pos);
		double c4 = cross(b.a.pos, b.b.pos, a.b.pos);
		return c3*c4 < 0;
	}

	private double cross(Point3d a, Point3d b, Point3d c) {
		Vector3d v1 = new Vector3d(b.x-a.x, b.y-a.y, b.z-a.z);
		Vector3d v2 = new Vector3d(c.x-a.x, c.y-a.y, c.z-a.z);
		Vector3d v3 = new Vector3d();
		v3.cross(v1, v2);
		return v3.z;
	}

}
